//UserConv.cc (modified)

#include <iostream>
using namespace std;

class Point3D;

class Point2D {
  int x;
  int y;
public:
  Point2D(int p, int q) :
    x(p), y(q) 
  {
    cout << "Point2D::Point2D" << endl;
  }
  operator Point3D();
};

class Point3D {
  int x;
  int y;
  int z;
public:
  Point3D(int p, int q, int r) : x(p), y(q)
  {
    cout << "Point3D::Point3D" << endl;
    z = r;
  }
  operator int () const 
  {
    cout << "Point3D::operator int ()" << endl;
    return (x + y + z);
  }
  friend ostream& operator<<(ostream& os, const Point3D& point);
};

ostream& operator<<(ostream& os, const Point3D& point) 
{
  cout << "operator<<(ostream& os, const Point3D& point)" << endl;
  os << "(" << point.x <<", " << point.y << ", " << point.z << ")";
  return os;
}

inline Point2D::operator Point3D() 
{
  cout << "inline Point2D::operator Point3D() {" << endl;
  return Point3D( x, y, 0 );
}

int main() 
{
  cout << "Point2D p2D(3, 4)" << endl;
  Point2D p2D(3, 4);
  cout << endl << "cout << p2D" << endl;
  cout << p2D << endl; // (3, 4, 0) 
  cout << endl << "Point3D p3D(1, 2, 3)" << endl;
  Point3D p3D(1, 2, 3); 
  cout << endl << "p3D - 1" << endl;
  cout << p3D - 1 << endl; // 5
  return 0;
}

/*

Point2D p2D(3, 4)
Point2D::Point2D

cout << p2D
inline Point2D::operator Point3D() {
Point3D::Point3D
operator<<(ostream& os, const Point3D& point)
(3, 4, 0)

Point3D p3D(1, 2, 3)
Point3D::Point3D

p3D - 1
Point3D::operator int ()
5

*/
